import datetime

from django.db import models
from django.contrib.auth.models import User
import django.utils

# h3. Quiz 

# A Quiz has Questions and Answers attached to it. The creator of a
# Quiz is special -- his or her answers to the questions will be used
# as the answer key. The quiz can have a final date, at which point no
# further changes to answers by users will be accepted. If this is set
# to Null, then the quiz is locked as soon as the user commits their
# first set of answers. The @template@ field is used to specify a
# specific template file to present the quiz in. Otherwise the default
# will be used.

class Quiz(models.Model):
    title    = models.CharField(max_length=200)
    about    = models.TextField()
    final    = models.DateTimeField(
        help_text="When to lock quiz", null=True, blank=True)
    template = models.CharField(
        help_text="Name of quiz page template file to use",
        max_length=32, null=True, blank=True, default="")
    creator  = models.ForeignKey(User, related_name="+")
    created  = models.DateTimeField("When quiz created")
    changed  = models.DateTimeField("When quiz changed")

    class Meta:
        verbose_name_plural = "Quizzes"

    def __unicode__(my):
        return my.title


    def remaining_seconds(my):
        "( my -- seconds) Computes time remaining for quiz."

        if not my.final: return 0

        try: left = my.final - django.utils.timezone.now()
        except AttributeError: # Old django, no timezone library.
            left = my.final - datetime.datetime.now()
        return (left.days * 86400) + left.seconds


    def open(my):
        "( my -- f) Determine if quiz is still available."

        left = my.remaining_seconds()
        # p(note). This should also do something about immediate
        # quizzes... jrlf 2013-02-11
        return left < 0


    def remaining(my):
        "( my -- string) Formats amount of time remaining until close."

        left = my.remaining_seconds()
        if not left: return "immediate"
        if left < 0: return "closed"
        
        days, r = divmod(left, 86400)
        hours, r = divmod(r, 3600)
        minutes, seconds = divmod(r, 60)

        return "%s days, %02d:%02d:%02d" % (days, hours, minutes, seconds)
    remaining.admin_order_field = "remaining"
    remaining.short_description = "Time remaining?"


# h3. Question

# Questions are hierarchical -- they can be parented to one another
# _ad infinitum_. Once they bottom out, they become the possible
# answers for next most recent question. This allows the contruction
# of multi-level categories like this:

# * Best Actor?
# ** In a leading role?
# *** Piers Brosnan
# *** Colin Mochrie
# ** In a supporting role?
# *** Bill Murray

# "In a leading role?" and "In a supporting role?" is parented to
# "Best Actor?". The actors names are parented to the respective
# category. Since they don't have any child nodes, they'll be
# presented as the possible answers.

class Question(models.Model):
    quiz   = models.ForeignKey(Quiz, related_name="questions")
    order  = models.IntegerField(default=0)
    parent = models.ForeignKey("self", related_name="children", null=True, blank=True)
    text   = models.CharField(max_length=250)
    about  = models.TextField(null=True, blank=True)

    def __unicode__(my):
        return "%s: %s" % (my.quiz.title, my.text)


# h3. Answer

# An answer associates a Question element with a user. If that user's
# association matches that of the Quiz creator, then the answer is
# correct. Otherwise, it's wrong.

# p(note). I'm not _sure_ I should attempt to track the question as
# well as the answer. The main reason for doing it is that it allows
# me to keep track of changes to the answer (in the context of the
# question) and makes it easier to get answers by all users to a
# particular question. However, it stores more information than is
# strictly necessary and could lead to unfindable results. jrlf
# 2013-02-07

class Answer(models.Model):
    quiz     = models.ForeignKey(Quiz, related_name="answers")
    user     = models.ForeignKey(User, related_name="+")
    question = models.ForeignKey(Question, related_name="answers")
    answer   = models.ForeignKey(Question, related_name="+")
    changed  = models.DateTimeField(help_text="When was answer last changed")
    changes  = models.IntegerField(default=0)

    def __unicode__(my):
        return "%s: %s -> %s" % (
            my.user.username, my.question.text, my.answer.text)
